﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WorkStation.UI.Controls
{
    public class MotionCoordinate
    {
        private List<MotionShape> _shapes;
        private int _setMargin = 0;
        private MotionShape _axis;
        private TextMotion _axisText;
        private CircleGraduation _circleGraduation;
        private PieMotion _pie;
        private List<LineMotion> _graduations;
        private List<TextMotion> _graduationText;
        private List<LineMotion> _gridLines;
        public string Description;
        private double _negativeLimit;
        public double NegativeLimit
        {
            get { return _negativeLimit; }
            set { _negativeLimit = value; }
        }
        private double _positiveLimit;
        public double PositiveLimit
        {
            get { return _positiveLimit; }
            set { _positiveLimit = value; }
        }
        private AxisDir _direction;
        public AxisDir Direction
        {
            get { return _direction; }
            set { _direction = value; }
        }
        private AxisLocation _location;
        public AxisLocation Location
        {
            get { return _location; }
            set { _location = value; }
        }
        private double _gridInterval = 5;
        public double GridInterval
        {
            get { return _gridInterval; }
            set { _gridInterval = value; }
        }
        private double _showNegative;
        public double ShowNegative
        {
            get { return _showNegative; }
            set { _showNegative = value; }
        }
        private double _showPositive;
        public double ShowPositive
        {
            get { return _showPositive; }
            set { _showPositive = value; }
        }
        public Color PaintColor { get; set; } = Color.DimGray;
        public bool IsCCW { get; set; }
        public MotionCoordinate(string description, List<MotionShape> shapes)
        {
            this.Description = description;
            this._shapes = shapes;
        }
        public void Update(int totalWidth, int totalHeight, int marginLeft, int marginUp, bool isResize = false)
        {
            double graduationInterval = 200;
            if (_axis == null && _direction != AxisDir.Circle)
            {
                _axis = new LineMotion();
                (_axis as LineMotion).Style = System.Drawing.Drawing2D.DashStyle.Solid;
                _axis.LineWidth = 4;
                _axis.PaintColor = PaintColor;
                (_axis as LineMotion).EnableEndCap = true;
                _shapes.Add(_axis);
            }
            else if(_axis == null && _direction == AxisDir.Circle)
            {
                _axis = new CircleMotion();
                _axis.LineWidth = 4;
                //_axis.IsFill = true;
                _axis.PaintColor = Color.DimGray;
                _axis.FillColor = Color.DeepPink;
                _axis.Alpha = 40;
                _shapes.Add(_axis);

                _circleGraduation = new CircleGraduation("_circleGraduation");
                _circleGraduation.LineWidth = 2;
                _circleGraduation.PaintColor = Color.DimGray;
                _circleGraduation.IsCCW = this.IsCCW;
                _shapes.Add(_circleGraduation);

                _pie = new PieMotion("pie");
                _pie.FillColor = Color.LawnGreen;
                _pie.SecondColor = Color.Coral;
                _pie.Alpha = 128;
                _pie.StartAngle = (float)_showNegative;
                _pie.EndAngle = (float)_showPositive;
                _shapes.Add(_pie);
            }
            if (_axisText == null)
            {
                _axisText = new TextMotion("axisText");
                if (this.Direction == AxisDir.Circle)
                {
                    _axisText.Text = $"{this.Description}(°)";
                    _axisText.RotateAngle = Direction == AxisDir.Up2Down || Direction == AxisDir.Down2Up ? -90 : 0;
                    _axisText.PaintColor = Color.Black;
                    _axisText.FontName = "黑体";
                    _axisText.FontSize = 14f;
                }
                else
                {
                    _axisText.Text = $"{this.Description}(mm)";
                    _axisText.RotateAngle = Direction == AxisDir.Up2Down || Direction == AxisDir.Down2Up ? -90 : 0;
                    _axisText.PaintColor = Color.Black;
                    _axisText.FontName = "黑体";
                    _axisText.FontSize = 14f;
                }
                _shapes.Add(_axisText);
            }
            if ((_direction == AxisDir.Left2Right || _direction == AxisDir.Right2Left) && _location == AxisLocation.Up)
            {
                (_axis as LineMotion).StartPoint = _direction == AxisDir.Left2Right ? new PointF(marginLeft, marginUp) : new PointF(totalWidth + marginLeft, marginUp);
                (_axis as LineMotion).EndPoint = _direction == AxisDir.Left2Right ? new PointF(totalWidth + marginLeft, marginUp) : new PointF(marginLeft, marginUp);
            }
            else if ((_direction == AxisDir.Left2Right || _direction == AxisDir.Right2Left) && _location == AxisLocation.Down)
            {
                (_axis as LineMotion).StartPoint = _direction == AxisDir.Left2Right ? new PointF(marginLeft, marginUp + totalHeight) : new PointF(totalWidth + marginLeft, marginUp + totalHeight);
                (_axis as LineMotion).EndPoint = _direction == AxisDir.Left2Right ? new PointF(totalWidth + marginLeft, marginUp + totalHeight) : new PointF(marginLeft, marginUp + totalHeight);
            }
            else if ((_direction == AxisDir.Up2Down || _direction == AxisDir.Down2Up) && _location == AxisLocation.Left)
            {
                (_axis as LineMotion).StartPoint = _direction == AxisDir.Up2Down ? new PointF(marginLeft, marginUp) : new PointF(marginLeft, marginUp + totalHeight);
                (_axis as LineMotion).EndPoint = _direction == AxisDir.Up2Down ? new PointF(marginLeft, marginUp + totalHeight) : new PointF(marginLeft, marginUp);
            }
            else if ((_direction == AxisDir.Up2Down || _direction == AxisDir.Down2Up) && _location == AxisLocation.Right)
            {
                (_axis as LineMotion).StartPoint = _direction == AxisDir.Up2Down ? new PointF(marginLeft + totalWidth, marginUp) : new PointF(marginLeft + totalWidth, marginUp + totalHeight);
                (_axis as LineMotion).EndPoint = _direction == AxisDir.Up2Down ? new PointF(marginLeft + totalWidth, marginUp + totalHeight) : new PointF(marginLeft + totalWidth, marginUp);
            }
            else if(_direction == AxisDir.Circle)
            {
                (_axis as CircleMotion).CenterPoint = totalWidth < totalHeight ? new PointF((float)(marginLeft + totalWidth / 2), (float)(marginUp + totalHeight / 2)) : new PointF((float)(marginLeft + totalWidth / 2), (float)(marginUp + totalHeight / 2));
                (_axis as CircleMotion).Radius = totalWidth < totalHeight ? totalWidth / 2 : totalHeight / 2;
                _circleGraduation.CenterPoint = totalWidth < totalHeight ? new PointF((float)(marginLeft + totalWidth / 2), (float)(marginUp + totalHeight / 2)) : new PointF((float)(marginLeft + totalWidth / 2), (float)(marginUp + totalHeight / 2));
                _circleGraduation.Radius = totalWidth < totalHeight ? totalWidth / 2 : totalHeight / 2;
                _circleGraduation.IsCCW = this.IsCCW;
                _pie.CenterPoint = totalWidth < totalHeight ? new PointF((float)(marginLeft + totalWidth / 2), (float)(marginUp + totalHeight / 2)) : new PointF((float)(marginLeft + totalWidth / 2), (float)(marginUp + totalHeight / 2));
                _pie.Radius = totalWidth < totalHeight ? totalWidth / 2 : totalHeight / 2;
            }
            if (_graduations == null && !isResize)
            {
                _graduations = new List<LineMotion>();
                _graduationText = new List<TextMotion>();
                int negIndex = 0;
                int posIndex = 0;
                int increment = 0;
                if ((_direction == AxisDir.Left2Right || _direction == AxisDir.Right2Left))
                {
                    negIndex = _direction == AxisDir.Left2Right ? -2000 : -2000;
                    posIndex = _direction == AxisDir.Left2Right ? 2000 : 2000;
                    increment = (int)graduationInterval;
                }
                else if((_direction == AxisDir.Up2Down || _direction == AxisDir.Down2Up))
                {
                    negIndex = _direction == AxisDir.Up2Down ? -2000 : -2000;
                    posIndex = _direction == AxisDir.Up2Down ? 2000 : 2000;
                    increment = (int)graduationInterval;
                }
                if (_direction == AxisDir.Left2Right || _direction == AxisDir.Right2Left)
                {
                    for (int i = negIndex; i < posIndex; i += increment)
                    {
                        if (i >= _showNegative && i <= _showPositive)
                        {
                            LineMotion l = new LineMotion($"{Description}_graduation_{i}");
                            l.Style = System.Drawing.Drawing2D.DashStyle.Solid;
                            l.LineWidth = 2;
                            l.PaintColor = PaintColor;
                            l.EnableEndCap = false;
                            l.Tag = i;
                            _graduations.Add(l);

                            TextMotion t = new TextMotion($"{Description}_graduationText_{i}");
                            t.PaintColor = Color.Black;
                            t.FontName = "微软雅黑";
                            t.FontSize = 10f;
                            t.Text = i.ToString("0.0");
                            _graduationText.Add(t);
                        }
                    }
                }
                else if ((_direction == AxisDir.Up2Down || _direction == AxisDir.Down2Up))
                {
                    for (int i = negIndex; i < posIndex; i += increment)
                    {
                        if (i >= _showNegative && i <= _showPositive)
                        {
                            LineMotion l = new LineMotion($"{Description}_graduation_{i}");
                            l.Style = System.Drawing.Drawing2D.DashStyle.Solid;
                            l.LineWidth = 1;
                            l.PaintColor = PaintColor;
                            l.EnableEndCap = false;
                            l.Tag = i;
                            _graduations.Add(l);

                            TextMotion t = new TextMotion($"{Description}_graduationText_{i}");
                            t.PaintColor = Color.Black;
                            t.FontName = "微软雅黑";
                            t.FontSize = 10f;
                            t.Text = i.ToString("0.0");
                            _graduationText.Add(t);
                        }
                    }
                }
                for (int i = 0; i < _graduations.Count; i++)
                {
                    _shapes.Add(_graduations[i]);
                }
                for (int i = 0; i < _graduationText.Count; i++)
                {
                    _shapes.Add(_graduationText[i]);
                }
            }
            else if (isResize)
            {
                _graduations = new List<LineMotion>();
                _graduationText = new List<TextMotion>();
                _shapes.RemoveAll(s => { return !string.IsNullOrEmpty(s.Description) && s.Description.Contains($"{Description}_graduation_"); });
                _shapes.RemoveAll(s => { return !string.IsNullOrEmpty(s.Description) && s.Description.Contains($"{Description}_graduationText_"); });
                _shapes.RemoveAll(s => { return !string.IsNullOrEmpty(s.Description) && s.Description.Contains($"_circleGraduation"); });
                int negIndex = 0;
                int posIndex = 0;
                int increment = 0;
                if ((_direction == AxisDir.Left2Right || _direction == AxisDir.Right2Left))
                {
                    negIndex = _direction == AxisDir.Left2Right ? -2000 : -2000;
                    posIndex = _direction == AxisDir.Left2Right ? 2000 : 2000;
                    increment = (int)graduationInterval;
                }
                else if ((_direction == AxisDir.Up2Down || _direction == AxisDir.Down2Up))
                {
                    negIndex = _direction == AxisDir.Up2Down ? -2000 : -2000;
                    posIndex = _direction == AxisDir.Up2Down ? 2000 : 2000;
                    increment = (int)graduationInterval;
                }
                else if (_direction == AxisDir.Circle)
                {
                    _circleGraduation = new CircleGraduation("_circleGraduation");
                    _circleGraduation.LineWidth = 2;
                    _circleGraduation.PaintColor = Color.DimGray;
                    _circleGraduation.IsCCW = this.IsCCW;
                    _shapes.Add(_circleGraduation);
                }
                if (_direction == AxisDir.Left2Right || _direction == AxisDir.Right2Left)
                {
                    for (int i = negIndex; i < posIndex; i += increment)
                    {
                        if (i >= _showNegative && i <= _showPositive)
                        {
                            LineMotion l = new LineMotion($"{Description}_graduation_{i}");
                            l.Style = System.Drawing.Drawing2D.DashStyle.Solid;
                            l.LineWidth = 2;
                            l.PaintColor = PaintColor;
                            l.EnableEndCap = false;
                            l.Tag = i;
                            _graduations.Add(l);

                            TextMotion t = new TextMotion($"{Description}_graduationText_{i}");
                            t.PaintColor = Color.Black;
                            t.FontName = "微软雅黑";
                            t.FontSize = 10f;
                            t.Text = i.ToString("0.0");
                            _graduationText.Add(t);
                        }
                    }
                }
                else if ((_direction == AxisDir.Up2Down || _direction == AxisDir.Down2Up))
                {
                    for (int i = negIndex; i < posIndex; i += increment)
                    {
                        if (i >= _showNegative && i <= _showPositive)
                        {
                            LineMotion l = new LineMotion($"{Description}_graduation_{i}");
                            l.Style = System.Drawing.Drawing2D.DashStyle.Solid;
                            l.LineWidth = 1;
                            l.PaintColor = PaintColor;
                            l.EnableEndCap = false;
                            l.Tag = i;
                            _graduations.Add(l);

                            TextMotion t = new TextMotion($"{Description}_graduationText_{i}");
                            t.PaintColor = Color.Black;
                            t.FontName = "微软雅黑";
                            t.FontSize = 10f;
                            t.Text = i.ToString("0.0");
                            _graduationText.Add(t);
                        }
                    }
                }
                else if (_direction == AxisDir.Circle)
                {
                    _circleGraduation.CenterPoint = totalWidth < totalHeight ? new PointF((float)(marginLeft + totalWidth / 2), (float)(marginUp + totalHeight / 2)) : new PointF((float)(marginLeft + totalWidth / 2), (float)(marginUp + totalHeight / 2));
                    _circleGraduation.Radius = totalWidth < totalHeight ? totalWidth / 2 : totalHeight / 2;
                    _circleGraduation.IsCCW = this.IsCCW;
                }
                for (int i = 0; i < _graduations.Count; i++)
                {
                    _shapes.Add(_graduations[i]);
                }
                for (int i = 0; i < _graduationText.Count; i++)
                {
                    _shapes.Add(_graduationText[i]);
                }
            }
            double small = _location == AxisLocation.Down || _location == AxisLocation.Up ? (totalWidth - 2 * _setMargin) / ((_showPositive - _showNegative) / graduationInterval) : (totalHeight - 2 * _setMargin) / ((_showPositive - _showNegative) / graduationInterval);
            for (int i = 0; i < _graduations.Count; i++)
            {
                if (_location == AxisLocation.Down || _location == AxisLocation.Up)
                {
                    double val = Convert.ToDouble(_graduations[i].Tag);
                    double pos = _direction == AxisDir.Left2Right ? (val - _showNegative) / (_showPositive - _showNegative) * (totalWidth - 2 * _setMargin) + _setMargin + marginLeft : (_showPositive - val) / (_showPositive - _showNegative) * (totalWidth - 2 * _setMargin) + _setMargin + marginLeft;
                    _graduations[i].StartPoint = _location == AxisLocation.Down ? new PointF((float)pos, marginUp + totalHeight) : new PointF((float)pos, marginUp);
                    if (double.IsNaN(_graduations[i].StartPoint.X))
                    {

                    }
                    _graduations[i].EndPoint = _location == AxisLocation.Down ? new PointF((float)pos, marginUp - 4 + totalHeight) : new PointF((float)pos, marginUp + 4);
                    _graduationText[i].StartPoint = _location == AxisLocation.Down ? new PointF((float)(pos - 15), marginUp + 5 + totalHeight) : new PointF((float)(pos - 15), marginUp - 25);
                }
                //else if (_direction == AxisDir.Right2Left && _location == AxisLocation.Up)
                //{
                //    _graduations[i].StartPoint = new PointF((float)(margin1 + _setMargin + i * small), margin2);
                //    _graduations[i].EndPoint = new PointF((float)(margin1 + _setMargin + i * small), margin2 + 4);

                //    _graduationText[i].StartPoint = new PointF((float)(margin1 + _setMargin + i * small), margin2);
                //    //_graduationText[i].Text = (_showPositive - i * graduationInterval).ToString("0.0");
                //}
                else if (_location == AxisLocation.Right || _location == AxisLocation.Left)
                {
                    double val = Convert.ToDouble(_graduations[i].Tag);
                    double pos = _direction == AxisDir.Up2Down ? (val - _showNegative) / (_showPositive - _showNegative) * (totalHeight - 2 * _setMargin) + _setMargin + marginUp : (_showPositive - val) / (_showPositive - _showNegative) * (totalHeight - 2 * _setMargin) + _setMargin + marginUp;
                    _graduations[i].StartPoint = _location == AxisLocation.Right ? new PointF(marginLeft + totalWidth, (float)pos) : new PointF(marginLeft, (float)pos);
                    if (double.IsNaN(_graduations[i].StartPoint.Y))
                    {

                    }
                    _graduations[i].EndPoint = _location == AxisLocation.Right ? new PointF(marginLeft - 4 + totalWidth, (float)pos) : new PointF(marginLeft + 4, (float)pos);
                    _graduationText[i].StartPoint = _location == AxisLocation.Right ? new PointF(marginLeft - 52 + totalWidth, (float)(pos - 10)) : new PointF(marginLeft - 52, (float)(pos - 10));
                }
            }
            if (_gridLines == null && !isResize)
            {
                _gridLines = new List<LineMotion>();
                int negIndex = 0;
                int posIndex = 0;
                int increment = 0;
                if ((_direction == AxisDir.Left2Right || _direction == AxisDir.Right2Left))
                {
                    negIndex = _direction == AxisDir.Left2Right ? -2000 : 2000;
                    posIndex = _direction == AxisDir.Left2Right ? 2000 : -2000;
                    increment = _direction == AxisDir.Left2Right ? 5 : 5;
                }
                else if ((_direction == AxisDir.Up2Down || _direction == AxisDir.Down2Up))
                {
                    negIndex = _direction == AxisDir.Up2Down ? -2000 : 2000;
                    posIndex = _direction == AxisDir.Up2Down ? 2000 : -2000;
                    increment = _direction == AxisDir.Up2Down ? 5 : 5;
                }
                if ((_direction == AxisDir.Left2Right || _direction == AxisDir.Up2Down))
                {
                    for (int i = negIndex; i < posIndex; i += increment)
                    {
                        if (i >= _showNegative && i <= _showPositive)
                        {
                            LineMotion l = new LineMotion($"{Description}_grid_{i}");
                            l.Style = System.Drawing.Drawing2D.DashStyle.Dash;
                            l.LineWidth = 1;
                            l.PaintColor = Color.LightGray;
                            l.EnableEndCap = false;
                            l.Tag = i;
                            //_gridLines.Add(l);
                        }
                    }
                }
                else if ((_direction == AxisDir.Up2Down || _direction == AxisDir.Down2Up))
                {
                    for (int i = negIndex; i > posIndex; i -= increment)
                    {
                        if (i >= _showNegative && i <= _showPositive)
                        {
                            LineMotion l = new LineMotion($"{Description}_grid_{i}");
                            l.Style = System.Drawing.Drawing2D.DashStyle.Dash;
                            l.LineWidth = 1;
                            l.PaintColor = Color.LightGray;
                            l.EnableEndCap = false;
                            l.Tag = i;
                            //_gridLines.Add(l);
                        }
                    }
                }
                for (int i = 0; i < _gridLines.Count; i++)
                {
                    //_shapes.Add(_gridLines[i]);
                }
            }
            else if (isResize)
            {
                _gridLines = new List<LineMotion>();
                _shapes.RemoveAll(s => { return !string.IsNullOrEmpty(s.Description) && s.Description.Contains($"{Description}_grid_"); });
                int negIndex = 0;
                int posIndex = 0;
                int increment = 0;
                if ((_direction == AxisDir.Left2Right || _direction == AxisDir.Right2Left))
                {
                    negIndex = _direction == AxisDir.Left2Right ? -2000 : -2000;
                    posIndex = _direction == AxisDir.Left2Right ? 2000 : 2000;
                    increment = _direction == AxisDir.Left2Right ? 5 : 5;
                }
                else if ((_direction == AxisDir.Up2Down || _direction == AxisDir.Down2Up))
                {
                    negIndex = _direction == AxisDir.Up2Down ? -2000 : 2000;
                    posIndex = _direction == AxisDir.Up2Down ? 2000 : -2000;
                    increment = _direction == AxisDir.Up2Down ? 5 : 5;
                }
                if (_direction == AxisDir.Left2Right || _direction == AxisDir.Up2Down)
                {
                    for (int i = negIndex; i < posIndex; i += increment)
                    {
                        if (i >= _showNegative && i <= _showPositive)
                        {
                            LineMotion l = new LineMotion($"{Description}_grid_{i}");
                            l.Style = System.Drawing.Drawing2D.DashStyle.Dash;
                            l.LineWidth = 1;
                            l.PaintColor = Color.LightGray;
                            l.EnableEndCap = false;
                            l.Tag = i;
                            //_gridLines.Add(l);
                        }
                    }
                }
                else
                {
                    for (int i = negIndex; i > posIndex; i -= increment)
                    {
                        if (i >= _showNegative && i <= _showPositive)
                        {
                            LineMotion l = new LineMotion($"{Description}_grid_{i}");
                            l.Style = System.Drawing.Drawing2D.DashStyle.Dash;
                            l.LineWidth = 1;
                            l.PaintColor = Color.LightGray;
                            l.EnableEndCap = false;
                            l.Tag = i;
                            //_gridLines.Add(l);
                        }
                    }
                }
                for (int i = 0; i < _gridLines.Count; i++)
                {
                    //_shapes.Add(_gridLines[i]);
                }
            }
            double smallGrid = _location == AxisLocation.Down || _location == AxisLocation.Up ? (totalWidth - 2 * _setMargin) / ((_showPositive - _showNegative) / _gridInterval) : (totalHeight - 2 * _setMargin) / ((_showPositive - _showNegative) / _gridInterval);
            for (int i = 0; i < _gridLines.Count; i++)
            {
                if (_location == AxisLocation.Down || _location == AxisLocation.Up)
                {
                    double val = Convert.ToDouble(_gridLines[i].Tag);
                    double pos = _direction == AxisDir.Left2Right ? (val - _showNegative) / (_showPositive - _showNegative) * (totalWidth - 2 * _setMargin) + _setMargin + marginLeft : (_showPositive - val) / (_showPositive - _showNegative) * (totalWidth - 2 * _setMargin) + _setMargin + marginLeft;
                    _gridLines[i].StartPoint = new PointF((float)pos, marginUp);
                    _gridLines[i].EndPoint = new PointF((float)pos, marginUp + totalHeight);
                }
                else if (_location == AxisLocation.Right || _location == AxisLocation.Left)
                {
                    double val = Convert.ToDouble(_gridLines[i].Tag);
                    double pos = _direction == AxisDir.Up2Down ? (val - _showNegative) / (_showPositive - _showNegative) * (totalHeight - 2 * _setMargin) + _setMargin + marginUp : (_showPositive - val) / (_showPositive - _showNegative) * (totalHeight - 2 * _setMargin) + _setMargin + marginUp;
                    _gridLines[i].StartPoint = new PointF(marginLeft, (float)pos);
                    _gridLines[i].EndPoint = new PointF(marginLeft + totalWidth, (float)pos);
                }
            }
            if (this._axisText != null)
            {
                if (Direction == AxisDir.Up2Down || Direction == AxisDir.Down2Up)
                {
                    this._axisText.StartPoint = new PointF(10, marginUp + totalHeight / 2);
                }
                else
                {
                    if(Direction == AxisDir.Circle)
                        this._axisText.StartPoint = new PointF(marginLeft + totalWidth - 30, 10);
                    else
                        this._axisText.StartPoint = new PointF(marginLeft + totalWidth / 2, 10);
                }
            }
        }
        public void GetActualPosition(int x, int y, int marginLeft, int marginUp, int totalWidth, int totalHeight, out double text, out PointF pos)
        {
            text = 0;
            pos = new Point();
            if(_direction == AxisDir.Left2Right || _direction == AxisDir.Right2Left)
            {
                int relPos = x - marginLeft - _setMargin;
                double percent = relPos * 1.0 / (totalWidth - _setMargin * 2);
                double offset = percent * (_showPositive - _showNegative);
                if (_direction == AxisDir.Left2Right)
                {
                    text = _showNegative + offset;
                    pos = new PointF(x, marginUp);
                }
                else
                {
                    text = _showNegative + (_showPositive - _showNegative - offset);
                    pos = new PointF(x, marginUp);
                }
            }
            else if (_direction == AxisDir.Up2Down || _direction == AxisDir.Down2Up)
            {
                int relPos = y - marginUp - _setMargin;
                double percent = relPos * 1.0 / (totalHeight - _setMargin * 2);
                double offset = percent * (_showPositive - _showNegative);
                if (_direction == AxisDir.Up2Down)
                {
                    text = _showNegative + offset;
                    pos = new PointF(marginLeft, y);
                }
                else
                {
                    text = _showNegative + (_showPositive - _showNegative - offset);
                    pos = new PointF(marginLeft, y);
                }
            }
            else if(_direction == AxisDir.Circle)
            {
                PointF center = totalWidth < totalHeight ? new PointF((float)(marginLeft + totalWidth / 2), (float)(marginUp + totalHeight / 2)) : new PointF((float)(marginLeft + totalWidth / 2), (float)(marginUp + totalHeight / 2));
                double a = Math.Atan((y - center.Y) / (x - center.X)) * 180 / Math.PI;
                
                if(x <= center.X && y >= center.Y)
                {
                    if (IsCCW)
                    {
                        text = -180-a;
                    }
                    else
                    {
                        text = 180 + a;
                    }
                }
                else if(x <=center.X && y<center.Y)
                {
                    if (IsCCW)
                    {
                        text = 180 - a;
                    }
                    else
                    {
                        text = a - 180;
                    }
                }
                else
                {
                    if (IsCCW)
                    {
                        text = -a;
                    }
                    else
                    {
                        text = a;
                    }
                }
                double p1, p2;
                GetBoardPosition(text, totalWidth, totalHeight, marginLeft, marginUp, AxisDir.Circle, out p1, out p2);
                pos = new PointF((float)p1, (float)p2);
            }
        }
        public bool GetBoardPosition(double pos, int totalWidth, int totalHeight, int marginLeft, int marginUp, AxisDir direction, out double crdPos, out double crdPos2)
        {
            crdPos = 0;
            crdPos2 = 0;
            if (direction == AxisDir.Circle)
            {
                PointF center = totalWidth < totalHeight ? new PointF((float)(marginLeft + totalWidth / 2), (float)(marginUp + totalHeight / 2)) : new PointF((float)(marginLeft + totalWidth / 2), (float)(marginUp + totalHeight / 2));
                float radius = totalWidth < totalHeight ? totalWidth / 2 : totalHeight / 2;
                if (IsCCW)
                {
                    double a = (-pos * Math.PI / 180);
                    crdPos = center.X + radius * Math.Cos(a);
                    crdPos2 = center.Y + radius * Math.Sin(a);
                }
                else
                {
                    double a = (pos * Math.PI / 180);
                    crdPos = center.X + radius * Math.Cos(a);
                    crdPos2 = center.Y + radius * Math.Sin(a);
                }
            }
            else
            {
                if (pos < _showNegative || pos > _showPositive)
                    return false;
                if (direction == AxisDir.Up2Down)
                    crdPos = (pos - _showNegative) / (_showPositive - _showNegative) * (totalHeight - 2 * _setMargin) + _setMargin + marginUp;
                else if(direction == AxisDir.Left2Right)
                    crdPos = (pos - _showNegative) / (_showPositive - _showNegative) * (totalWidth - 2 * _setMargin) + _setMargin + marginLeft;
                else if(direction == AxisDir.Down2Up)
                    crdPos = ((_showPositive - _showNegative) - (pos - _showNegative)) / (_showPositive - _showNegative) * (totalHeight - 2 * _setMargin) + _setMargin + marginUp;
                else if(direction == AxisDir.Right2Left)
                    crdPos = ((_showPositive - _showNegative) - (pos - _showNegative)) / (_showPositive - _showNegative) * (totalWidth - 2 * _setMargin) + _setMargin + marginLeft;
            }
            return true;
        }
        public void SetPieLimit(double start, double end)
        {
            //_pie.StartAngle = (float)_showNegative;
            //_pie.EndAngle = (float)_showPositive;
            _pie.StartAngle = (float)start;
            _pie.EndAngle = (float)end;
        }
        public void SetPieClock(bool isCCW)
        {
            _pie.IsCCW = IsCCW;
        }
    }
    public enum AxisDir
    {
        Left2Right,
        Right2Left,
        Up2Down,
        Down2Up,
        Circle,
    }
    public enum AxisLocation
    {
        Up,
        Down,
        Left,
        Right,
    }
}
